/**
 * Created by Jessi on 2018/1/2.
 */
import moment from 'moment';
export default class extends think.Service {
    constructor() {
        super();
        this.caseModel = this.db['oa_case'];
        this.eventModel = this.db['cms_event'];
        this.userModel = this.db['sys_user'];
        this.orgModel = this.db['sys_org'];
        this.partModel = this.db['cms_parts'];
        this.taskModel = this.db['bpmn_hi_taskinst'];
        this.sysAttachmentModel = this.db['sys_attachment'];
        this.areaModel = this.db['cms_area'];
        // this.caseModel.belongsToMany(this.taskModel,{ through:this.hi_procinstModel,
        // foreignKey:'proc_inst_id', otherKey:'proc_inst_id' })
        this
            .caseModel
            .belongsTo(this.areaModel, {
                foreignKey: 'area_code',
                targetKey: 'area_code'
            });
        this
            .caseModel
            .belongsTo(this.userModel, {
                foreignKey: 'create_by'
            });
        this
            .userModel
            .belongsTo(this.orgModel, {
                foreignKey: 'org_id',
                targetKey: 'id'
            });

        this.hi_procinstModel = this.db['bpmn_hi_procinst'];
        this
            .caseModel
            .belongsTo(this.hi_procinstModel, {
                foreignKey: 'proc_inst_id'
            });
        this
            .hi_procinstModel
            .hasMany(this.taskModel, {
                foreignKey: 'proc_inst_id',
                targetKey: 'id'
            });
        this
            .taskModel
            .belongsTo(this.userModel, {
                foreignKey: 'assignee',
                targetKey: 'username'
            });
        this
            .caseModel
            .hasMany(this.sysAttachmentModel, {
                // as: 'attachImgPath',
                foreignKey: 'businesskey',
                targetKey: 'id'
            });

        this
            .caseModel
            .belongsTo(this.partModel, {
                // as: 'partC',
                foreignKey: 'businesskey',
                targetKey: 'id'
            });
    }

    /**
   * 通过businesskey查询案件信息
   *
   * @param {any} data
   * @returns {Array} 案件数组
   */
    async getCaseByKey(data) {
        const Op = this.db.Sequelize.Op;
        const where = {
            businesskey: data.businesskey,
            del_flag: 0
        };
        try {
            const Res = await this
                .caseModel
                .findAll({
                    where: where
                });
            return Res;
        } catch (error) {
            return this
                .exceptionService
                .handleError(error);
        }
    }

    /**
   * 查询案件信息
   *
   * @param {any} data
   * @returns
   */
    async getCaseAll(userInfo) {
        const where = {
            del_flag: 0
        };
        let orgWhere = {};
        const newWhere = await this
            .BaseService
            .getDataScopeWhere(userInfo, 1);
        if (newWhere instanceof Object) {
            orgWhere = newWhere;
        } else {
            if (Number(newWhere) == 4) {
                const {
                    userId
                } = userInfo;
                where.create_by = userId;
            }
        }

        try {
            const Res = await this
                .caseModel
                .findAll({
                    where: where,
                    order: [
                        ['create_date', 'DESC']
                    ],
                    include: [{
                        model: this.userModel,
                        attributes: [
                            'id', 'realname'
                        ],
                        include: [{
                            model: this.orgModel,
                            attributes: [
                                'id', 'org_name'
                            ],
                            where: orgWhere,
                            required: true
                        }],
                        required: true

                    }, {
                        model: this.hi_procinstModel,
                        attributes: ['status'],
                        required: true
                    }]
                });
            return Res;
        } catch (error) {
            return this
                .exceptionService
                .handleError(error);
        }
    }

    /**
   * 事件立案申请
   */
    async createCase(data) {
        console.log('163163', data);
        if (!data.id) {
            data.id = think.uuid('v1');
        }
        const ID = data.id;
        // data.businesskey = null;
        data.update_date = new Date();

        data.status = 5;
        data.create_date = new Date();
        data.case_code = `陆城管源[${(moment().format('YYYY'))}]${moment().format('MMDDhhmmssSSS')}${Math.floor(Math.random() * 899 + 100)}`;
        const where = {
            id: ID
        };
        if (data.case_type == '部件') {
            data.case_type = 2
        } else if (data.case_type == '事件') {
            data.case_type = 1
        }
        const state_data = {
            ObjCode: data.ObjCode,
            status: data.status,
            ObjName: data.ObjName,
            DeptCode1: data.DeptCode1,
            DeptName1: data.DeptName1,
            parent_name: data.parent_name,
            sub_name: data.sub_name,
            update_date: data.create_date,
            update_by: data.update_by,
            group_code: data.group_code,
            type: Number(data.case_type),
            remarks: data.remarks
        };
        try {
            const res = await this
                .caseModel
                .create(data);

            if (res) {
                const result = await this
                    .eventModel
                    .update(state_data, {
                        where: where
                    });

                return await this
                    .caseModel
                    .findOne({
                        where: where
                    });
            } else {
                return res;
            }
        } catch (error) {
            return this
                .exceptionService
                .handleError(error);
        }
    }

    /**
   * byId查询
   */

    async caseById(data) {
        const ID = data.id;
        const where = {
            id: ID
        };
        try {
            return await this
                .caseModel
                .findOne({
                    where: where
                });
        } catch (error) {
            return this
                .exceptionService
                .handleError(error);
        }
    }

    /**
   * 部件立案申请
   */

    async createPartCase(data) {
        const queryData = {
            id: think.uuid('v1'),
            DeptCode1: data.DeptCode1 || null,
            DeptName1: data.DeptName1 || null,
            ObjPosition: data.address_name || null,
            BGID: data.BGID || null,
            case_code: `陆城管源[${(moment().format('YYYY'))}]${moment().format('MMDDhhmmssSSS')}${Math.floor(Math.random() * 899 + 100)}`,
            case_type: 2,
            parent_name: data.cms_parts_group.parent_id || '部件问题',
            sub_name: data.cms_parts_group.group_name || null,
            group_code: data.group_code || '07',
            create_by: data.create_by,
            update_by: data.update_by,
            create_date: new Date(),
            update_date: new Date(),
            remarks: data.Note || null,
            businesskey: data.id,
            baidu_x: data.baidu_x,
            baidu_y: data.baidu_y,
            del_flag: 0,
            area_code: data.area_code || null,
            proc_inst_id: data.proc_inst_id

        };
        data.update_date = new Date();
        const where = {
            id: data.id
        };
        const param_data = {
            id: think.uuid('v1'),
            user_id: data.userid,
            realpath: data.pic_path,
            create_date: new Date(),
            businesskey: queryData.id,
            file_name: data.cms_parts_group.group_name || null

        };

        try {
            const fileRes = await this.sysAttachmentModel.create(param_data);
            const res = await this
                .caseModel
                .create(queryData);

            if (!res.error) {
                const result = await this
                    .partModel
                    .update(data, {
                        where: where
                    });
                return result;
            } else {
                return res;
            }
        } catch (error) {
            return this
                .exceptionService
                .handleError(error);
        }
    }

    /**
   * 更新案件BGID
   */
    async updateCaseBGID(data) {
        const query = {
            BGID: data.BGID
        };
        const where = {
            id: data.id
        };
        try {
            return await this
                .caseModel
                .update(query, {
                    where: where
                });
        } catch (error) {
            return this
                .exceptionService
                .handleError(error);
        }
    }

    /**
   * 通过porcid查询案件信息
   *
   * @param {any} data  data.id
   * @returns
   */
    async getCaseByProcId(proc_inst_id) {
        const _this = this;
        const sql = `SELECT	oa_case.id,oa_case.DeptName1,bpmn_hi_procinst.overtime,bpmn_hi_procinst.duration,oa_case.ObjPosition,oa_case.case_code,oa_case.parent_name,oa_case.sub_name,oa_case.create_by,oa_case.remarks,sys_user.realname,u.realname update_name,oa_case.create_date,oa_case.update_date
FROM oa_case LEFT JOIN sys_user on sys_user.id=oa_case.create_by LEFT JOIN sys_user u on u.id=oa_case.update_by left join bpmn_hi_procinst on bpmn_hi_procinst.id=oa_case.proc_inst_id where oa_case.proc_inst_id= ${proc_inst_id}`;
        try {
            const Res = await _this
                .CrudService
                .querySql(sql);
            return Res;
        } catch (error) {
            return this
                .exceptionService
                .handleError(error);
        }
    }

    /**
   * 部门评价
   *
   * @returns
   */
    async getOrgEval(data) {
        data.orgList = data
            .orgList
            .replace('[', '(')
            .replace(']', ')');
        const FormDate = '';
        const sql = `SELECT a.org_code,a.org_name,(SELECT count(*) FROM oa_case c WHERE (c.DeptCode1 IN (
                        SELECT id FROM sys_org b WHERE b.parent_ids LIKE concat('%', a.parent_ids, a.id, ',%')
                    ) OR c.DeptCode1 = a.id ) ) AS totalCount,count( CASE WHEN bb. STATUS = 1 AND bb.id = cc.proc_inst_id THEN
                1 ELSE NULL END ) AS closeCount, count( CASE WHEN bb. STATUS = 2  AND bb.id = cc.proc_inst_id THEN
                1 ELSE NULL END ) AS openCount ,	count( CASE WHEN bb. STATUS = 0 AND bb.id = cc.proc_inst_id THEN
                        1 ELSE NULL END ) AS rejectCount FROM sys_org a LEFT JOIN oa_case cc ON ( ( cc.DeptCode1 IN (
                SELECT id FROM sys_org b WHERE b.parent_ids LIKE concat('%', a.parent_ids, a.id, ',%')
            ) OR cc.DeptCode1 = a.id ) ) LEFT JOIN bpmn_hi_procinst bb ON (bb.id = cc.proc_inst_id)
    WHERE a.id IN ${data.orgList} GROUP BY a.id`;
        try {
            const list = await this
                .db
                .sequelize
                .query(sql, {
                    type: this.db.sequelize.QueryTypes.SELECT
                });
            return list;
        } catch (err) {
            return this
                .exceptionService
                .handleError(err);
        }
    }

    /**
   * 查询案件列表
   */

    async all_case_list(data) {
        const Op = this.db.Sequelize.Op;
        data.start = (parseInt(data.page) - 1) * parseInt(data.pageSize);
        const where = {
            del_flag: 0
        };
        try {
            const result = await this
                .caseModel
                .findAndCountAll({
                    where: where,
                    limit: parseInt(data.pageSize),
                    offset: parseInt(data.start),
                    order: [
                        ['create_date', 'DESC']
                    ]
                });
            return result;
        } catch (error) {
            return this
                .exceptionService
                .handleError(error);
        }
    }

    async specific_case_list(data) {
        const Op = this.db.Sequelize.Op;
        data.start = (parseInt(data.page) - 1) * parseInt(data.pageSize);
        const where = {
            del_flag: 0
        };
        if (data.start_date && data.end_date) {
            where.create_date = {
                [Op.between]: [data.start_date, data.end_date]
            };
        }
        if (data.parent_name) {
            where.parent_name = data.parent_name;
        }
        if (data.sub_name) {
            where.sub_name = data.sub_name;
        }
        if (data.source) {
            where.source = data.source;
        }

        if (data.remarks) {
            where.remarks = {
                [Op.like]: '%' + data.remarks + '%'
            };
        }
        try {
            const result = await this
                .caseModel
                .findAndCountAll({
                    where: where,
                    limit: parseInt(data.pageSize),
                    offset: parseInt(data.start),
                    order: [
                        ['create_date', 'DESC']
                    ]
                });
            return result;
        } catch (error) {
            return this
                .exceptionService
                .handleError(error);
        }
    }

    async delete_case(data) {
        const Op = this.db.Sequelize.Op;
        const query = {
            del_flag: 1
        };
        let where = {};

        if (typeof (data.id) === 'string') { // 单条删除
            where = {
                id: data.id
            };
        } else { // 批量删除
            where = {
                id: {
                    [Op.in]: data.id
                }
            };
        }
        try {
            return await this
                .caseModel
                .update(query, {
                    where: where
                });
        } catch (error) {
            return this
                .exceptionService
                .handleError(error);
        }
    }

    /**
   * 获取所有同意状态的案件（分页）
   *
   * @param {*} data
   * @param {*} userInfo
   * @returns
   */
    async getCaseViaAll(data, userInfo) {
        const Op = this.db.Sequelize.Op;
        data.start = (parseInt(data.page) - 1) * parseInt(data.pageSize);

        const where = {
            case_type: data.case_type,
            del_flag: 0,
            remarks: {
                [Op.like]: '%' + data.remarks + '%'
            },
            case_code: {
                [Op.like]: '%' + data.case_code + '%'
            }
            // area_code: data.area_code
        };
        if (data.time) {
            const time = JSON.parse(data.time);
            where.create_date = {
                [Op.gt]: time[0],
                [Op.lt]: time[1]
            };
        }
        if (data.area_code) {
            where.area_code = data.area_code;
        }
        if (data.DeptCodes) {
            where.DeptCode1 = {
                [Op.in]: JSON.parse(data.DeptCodes)
            };
        }
        if (data.parent_name) {
            where.parent_name = data.parent_name;
        }
        let orgWhere = {};
        const newWhere = await this
            .BaseService
            .getDataScopeWhere(userInfo, 1);
        if (newWhere instanceof Object) {
            orgWhere = newWhere;
            console.log('orgWhere:', orgWhere);
        } else {
            if (Number(newWhere) == 4) {
                const {
                    userId
                } = userInfo;
                where.create_by = userId;
            }
        }

        const caseNewModel = {
            model: this.sysAttachmentModel,
            // as: 'attachImgPath',
            attributes: [
                ['realpath', 'imgPath']
            ]
        };
        const partnewModel = [];
        if (Number(data.case_type) != 1) {
            partnewModel.push({
                model: this.partModel,
                // as: 'partC',
                attributes: [
                    ['pic_path', 'imgPath']
                ]
            });
        }
        const include = [{
            model: this.userModel,
            attributes: [
                'id', 'realname'
            ],
            include: [{
                model: this.orgModel,
                attributes: [
                    'id', 'org_name'
                ],
                where: orgWhere,
                required: true
            }],
            required: true

        }, {
            model: this.hi_procinstModel,
            where: {
                status: 1
            },
            attributes: ['status', 'overtime', 'duration'],
            required: true,
            include: [{
                model: this.taskModel,
                // order: [     ['start_time', 'ASC'] ]
                include: [{
                    model: this.userModel,
                    attributes: ['id', 'realname']
                }]
            }]
        }, {
            model: this.areaModel,
            attributes: ['area_name']
        },
        caseNewModel
        ];
        const newinclude = [
            ...include,
            ...partnewModel
        ];
        try {
            const Res = await this
                .caseModel
                .findAndCountAll({
                    where: where,
                    limit: parseInt(data.pageSize),
                    offset: parseInt(data.start),
                    // order: [{model: this.hi_procinstModel}, 'start_time', 'ASC'],
                    order: [
                        [
                            'create_date', 'DESC'
                        ],
                        [
                            this.hi_procinstModel, this.taskModel, 'start_time', 'ASC'
                        ],
                        [this.hi_procinstModel, this.taskModel, 'id', 'ASC']

                    ],
                    distinct: true,
                    include: newinclude
                });
            return Res;
        } catch (error) {
            return this
                .exceptionService
                .handleError(error);
        }
    }

    async getPartsCase(data) {
        const start = (data.page - 1) * data.pageSize;
        let area_codeStr = '',
            create_dateStr = '';
        if (data.area_code) {
            area_codeStr = ` and oa_case.area_code=${data.area_code}`;
        }
        if (data.startTime) {
            create_dateStr = ` and oa_case.create_date between '${data.startTime}' and '${data.endTime}'`;
        }
        const sql = `select cms_area.area_name,oa_case.* from bpmn_hi_procinst
right JOIN oa_case on oa_case.proc_inst_id=bpmn_hi_procinst.id and oa_case.group_code='07' ${area_codeStr} ${create_dateStr}
left JOIN cms_area on cms_area.area_code=oa_case.area_code
where bpmn_hi_procinst.status=1 LIMIT ${start},${data.pageSize}`;
        const countSql = `select count(*) count from bpmn_hi_procinst
right JOIN oa_case on oa_case.proc_inst_id=bpmn_hi_procinst.id and oa_case.group_code='07' ${area_codeStr} ${create_dateStr}
where bpmn_hi_procinst.status=1 `;
        try {
            const Res = await this.CrudService.querySql(sql);
            const count = await this.CrudService.querySql(countSql);
            return {
                row: Res,
                count: count
            };
        } catch (error) {
            return this
                .exceptionService
                .handleError(error);
        }
    }
}
